/**
 * DateUtil工具类API速查表:
 * 1.得到当前时间 getCurrentDate()
 * 2.得到当前年份字符串 getCurrentYear()
 * 3.得到当前月份字符串 getCurrentMonth()
 * 4.得到当天字符串 getCurrentDay()
 * 5.得到当前星期字符串(星期几) getCurrentWeek()
 * 6.Date转化为String formatDate()
 * 7.String转化为Date parseDate()
 * 8.比较时间大小 compareToDate()
 * 9.得到给定时间的给定天数后的日期 getAppointDate()
 * 10.获取两个日期之间的天数 getDistanceOfTwoDate()
 * 11.获取过去的天数 pastDays()
 * 12.获取过去的小时 pastHour()
 * 13.获取过去的分钟  pastMinutes()
 * 14.得到本周的第一天  getFirstDayOfWeek()
 * 15.得到当月第一天 getFirstDayOfMonth()
 * 16.得到下月的第一天 getFirstDayOfNextMonth()
 * 17.根据生日获取年龄 getAgeByBirthDate()
 */
package com.ml.loan.common.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期时间工具类
 **/
public class DateUtil {

    public  static  String  DATE_FORMATTER = "yyyy-MM-dd";
    public  static  String  DATE_FORMATTER_S = "yyyy-M-d";
    public  static  String  DATETIME_FORMATTER = "yyyy-MM-dd HH:mm:ss";
    public  static  String  DATETIME_FORMATTER_S = "yyyy-M-d HH:mm:ss";
    public  static  String  NOCHARNOTIME_PATTERN = "yyyyMMdd";
    public  static  String  NOCHAR_PATTERN    = "yyyyMMddHHmmss";
    public  static  String NOSECOND_PATTERN  = "yyyyMMddHHmmssSSS";


    /**
     * 得到当前时间(yyyy-MM-dd HH:mm:ss)
     *
     * @return
     */
    public static String getCurrentDate() {
        return formatDate(new Date());
    }

    /**
     * 得到当前时间
     *
     * @param formate 格式
     * @return
     */
    public static String getCurrentDate(String formate) {
        return formatDate(new Date(), formate);
    }

    /**
     * 得到当前年份字符串
     */
    public static String getCurrentYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 得到当前月份字符串
     */
    public static String getCurrentMonth() {
        return formatDate(new Date(), "MM");
    }

    /**
     * 得到当天字符串
     */
    public static String getCurrentDay() {
        return formatDate(new Date(), "dd");
    }

    /**
     * 得到当前星期字符串(星期几)
     */
    public static String getCurrentWeek() {
        return formatDate(new Date(), "E");
    }

    /**
     * Date转化为String
     *
     * @param date
     * @param formate 格式
     * @return
     */
    public static String formatDate(Date date, String formate) {
        SimpleDateFormat sdf = new SimpleDateFormat(formate);
        return sdf.format(date);
    }

    /**
     * Date转化为String(yyyy-MM-dd HH:mm:ss)
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * String转化为Date
     *
     * @param date
     * @param formate
     * @return
     */
    public static Date parseDate(String date, String formate) {
        SimpleDateFormat sdf = new SimpleDateFormat(formate);
        try {
            return sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * String转化为Date
     *
     * @param date
     * @return
     */
    public static Date parseDate(String date) {
        return parseDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * @Description 根据毫秒判断时间间隔
     * @Author caozhuoxiang
     * @Date 2019/4/19 10:28
     * @param date1
     * @param date2
     * @return int
     **/
    public static int differentDaysByMillisecond(Date date1, Date date2)
    {
        int days = (int) ((date2.getTime() - date1.getTime()) / (1000*3600*24));
        return days;
    }

    /**
     * 比较时间大小
     *
     * @param first
     * @param second
     * @return 返回0 first等于second, 返回-1 first小于second,, 返回1 first大于second
     */
    public static int compareToDate(String first, String second, String pattern) {
        DateFormat df = new SimpleDateFormat(pattern);
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        try {
            cal1.setTime(df.parse(first));
            cal2.setTime(df.parse(second));
        } catch (ParseException e) {
            e.printStackTrace();
            System.out.println("比较时间错误");
        }
        int result = cal1.compareTo(cal2);
        if (result < 0) {
            return -1;
        } else if (result > 0) {
            return 1;
        }
        return 0;
    }

    /**
     * 比较时间大小
     *
     * @param first
     * @param second
     * @return 返回0 first等于second, 返回-1 first小于second,, 返回1 first大于second
     */
    public static int compareToDate(Date first, Date second) {
        int result = first.compareTo(second);
        if (result < 0) {
            return -1;
        } else if (result > 0) {
            return 1;
        }
        return 0;
    }

    /**
     * 得到给定时间的给定天数后的日期
     *
     * @return
     */
    public static Date getAppointDate(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, day);
        return calendar.getTime();
    }

    public static Date getAppointYearDate(Date date, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, year);
        return calendar.getTime();
    }

    public static Date getAppointMinuteDate(Date date, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    /**
     * 增加几个小时后的时间
     **/
    public static Date addHourDate(Date date, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, hour);
        return calendar.getTime();
    }

    /**
     * 增加几分钟后的时间
     **/
    public static Date addMinuteDate(Date date, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }


    /**
     * 获取两个日期之间的天数
     *
     * @param before
     * @param after
     * @return
     */
    public static double getDistanceOfTwoDate(Date before, Date after) {
        long beforeTime = before.getTime();
        long afterTime = after.getTime();
        return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
    }

    /**
     * 获取过去的天数
     *
     * @param date
     * @return
     */
    public static long pastDays(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取过去的小时
     *
     * @param date
     * @return
     */
    public static long pastHour(Date date) {
        long t =System.currentTimeMillis() - date.getTime();
        return t / (60 * 60 * 1000);
    }

    /**
     * 获取过去的分钟
     *
     * @param date
     * @return
     */
    public static long pastMinutes(Date date) {
        long t = System.currentTimeMillis() - date.getTime();
        return t / (60 * 1000);
    }

    /**
     * 得到本周的第一天
     *
     * @return
     */
    public static Date getFirstDayOfWeek() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return cal.getTime();
    }

    /**
     * 得到当月第一天
     *
     * @return
     */
    public static Date getFirstDayOfMonth() {
        Calendar cal = Calendar.getInstance();
        int firstDay = cal.getMinimum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, firstDay);
        cal.set(Calendar. HOUR_OF_DAY, 0);
        cal.set(Calendar. MINUTE, 0);
        cal.set(Calendar. SECOND, 0);
        return cal.getTime();
    }

    /**
     * 得到下月的第一天
     *
     * @return
     */
    public static Date getFirstDayOfNextMonth() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, +1);
        int firstDay = cal.getMinimum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, firstDay);
        return cal.getTime();
    }

    /**
     * 根据生日获取年龄
     *
     * @param birtnDay
     * @return
     */
    public static int getAgeByBirthDate(Date birtnDay) {
        Calendar cal = Calendar.getInstance();
        if (cal.before(birtnDay)) {
            return 0;
        }
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birtnDay);
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
        int age = yearNow - yearBirth;
        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                age--;
            }
        }
        return age;
    }

    public static LocalDate dateToLocalDate(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
        return localDateTime.toLocalDate();
    }

    public static Date initDateByDay(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date initDateByYesterday(){
        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(new Date());
        calendar.add(Calendar.DATE,-1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取几天前零点的时间
     * @param day
     * @return
     */
    public static Date initDateBeforeToday(Integer day){
        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(new Date());
        calendar.add(Calendar.DATE,-1*day);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }


    public static Long betweenDays(String a, String b) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");// 自定义时间格式
        Calendar calendar_a = Calendar.getInstance();// 获取日历对象
        Calendar calendar_b = Calendar.getInstance();

        Date date_a = null;
        Date date_b = null;

        try {
            date_a = simpleDateFormat.parse(a);//字符串转Date
            date_b = simpleDateFormat.parse(b);
            calendar_a.setTime(date_a);// 设置日历
            calendar_b.setTime(date_b);
        } catch (ParseException e) {
            e.printStackTrace();//格式化异常
        }

        long time_a = calendar_a.getTimeInMillis();
        long time_b = calendar_b.getTimeInMillis();

        long between_days = (time_b - time_a) / (1000 * 3600 * 24);//计算相差天数
        return between_days;
    }

    public static Long betweenDays(String a, String b, boolean isAbs) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");// 自定义时间格式
        Calendar calendar_a = Calendar.getInstance();// 获取日历对象
        Calendar calendar_b = Calendar.getInstance();

        Date date_a = null;
        Date date_b = null;

        try {
            date_a = simpleDateFormat.parse(a);//字符串转Date
            date_b = simpleDateFormat.parse(b);
            calendar_a.setTime(date_a);// 设置日历
            calendar_b.setTime(date_b);
        } catch (ParseException e) {
            e.printStackTrace();//格式化异常
        }

        long time_a = calendar_a.getTimeInMillis();
        long time_b = calendar_b.getTimeInMillis();

        long between_days = (time_b - time_a) / (1000 * 3600 * 24);//计算相差天数
        return isAbs?Math.abs(between_days):between_days;
    }


    public static List<String> getDaysBetweenTwoDays(String startDay, String endDay) throws ParseException {
        List<String> list = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//格式化为年月
        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();
        min.setTime(sdf.parse(startDay));
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), min.get(Calendar.DATE),0,0,0);
        max.setTime(sdf.parse(endDay));
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), max.get(Calendar.DATE),23,59,59);
        Calendar curr = min;
        while (curr.before(max)) {
            list.add(sdf.format(curr.getTime()));
            curr.add(Calendar.DATE, 1);
        }
        return list;
    }


    /**
     * 将String型格式化,比如想要将2011-11-11格式化成2011年11月11日,就StringPattern("2011-11-11","yyyy-MM-dd","yyyy年MM月dd日").
     * @param date String 想要格式化的日期
     * @param oldPattern String 想要格式化的日期的现有格式
     * @param newPattern String 想要格式化成什么格式
     * @return String
     */
    public static String StringPattern(String date, String oldPattern, String newPattern) {
        if (date == null || oldPattern == null || newPattern == null) {
            return "";
        }
        SimpleDateFormat sdf1 = new SimpleDateFormat(oldPattern) ;        // 实例化模板对象
        SimpleDateFormat sdf2 = new SimpleDateFormat(newPattern) ;        // 实例化模板对象
        Date d = null ;
        try{
            d = sdf1.parse(date) ;   // 将给定的字符串中的日期提取出来
        }catch(Exception e){            // 如果提供的字符串格式有错误，则进行异常处理
            e.printStackTrace() ;       // 打印异常信息
        }
        return sdf2.format(d);
    }


    public static String getToday(String format) {
        DateFormat df = new SimpleDateFormat(format);
        return df.format(new Date());
    }

    public static String getWeek(int num) {
        if(num>7||num<0) {
            throw new RuntimeException(num+"没有对应的星期");
        }
        String [] week = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
        return week[num];
    }

    /**
     * @descript:计算两个字符串日期相差的天数
     * @param date1 字符串日期1
     * @param date2 字符串日期2
     * @param format 日期格式化方式  format="yyyy-MM-dd"
     * @return
     */
    public static long dayDiff(String date1, String date2,String format) {
        SimpleDateFormat formater = new SimpleDateFormat(format);
        long diff=1;
        try {
            long d1 = formater.parse(date1).getTime();
            long d2 = formater.parse(date2).getTime();
            diff=(d1-d2)/(1000 * 60 * 60 * 24);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return diff;
    }


    /**
     * 获取多少秒之前的时间
     * @param ss
     * @return
     */
    public static String beforeSecondDateTime(Integer ss){
        SimpleDateFormat fd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, -ss);
        return fd.format(calendar.getTime());
    }

    public static Date asDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取
     * @param birthday
     * @return
     */
    public static int getAgeByBirth(Date birthday) {
        int age = 0;
        try {
            Calendar now = Calendar.getInstance();
            now.setTime(new Date());// 当前时间

            Calendar birth = Calendar.getInstance();
            birth.setTime(birthday);

            if (birth.after(now)) {//如果传入的时间，在当前时间的后面，返回0岁
                age = 0;
            } else {
                age = now.get(Calendar.YEAR) - birth.get(Calendar.YEAR);
                if (now.get(Calendar.DAY_OF_YEAR) > birth.get(Calendar.DAY_OF_YEAR)) {
                    age += 1;
                }
            }
            return age;
        } catch (Exception e) {//兼容性更强,异常后返回数据
            return 0;
        }
    }

    /**
     * 获取一个月前的date
     * @return
     */
    public static Date beforeOneMonthDate(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.DATE, -1);    //得到前一天
        cal.add(Calendar.MONTH, -1);    //得到前一个月
        Long date = cal.getTimeInMillis();
        String format = sdf.format(date);
        Date baforeMonthDate= null;
        try {
            baforeMonthDate = sdf.parse(format);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return baforeMonthDate;
    }

}
